package com.GPS_based_training.custom_components;

import com.GPS_based_training.progetto_so2_2014_2015.R;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * Class that define the custom component CompositeStats, which shows three texts with a
 * formatted style.
 * @author Andreas Scalas
 */
public class CompositeStats extends View {

	private String text1; //The first text
	private String text2; //The second text
	private String text3; //The third text
	
	private final float TEXT_SIZE_RATIO = 1 / 7.0F; //The ratio between the width of the canvas and the text size
	private final float TEXT_SHIFT_RATIO = 1 / 2.0F; //The text has to be shifted of an half of the text size in order to center it 
	private final float MIN_WIDTH_RATIO = 1 / 17.0F; //The ratio between the width of the canvas and the minimal axis of the texts
	private final float TEXT1_HEIGHT_RATIO = 1 / 6.0F; //The ratio between the height of the canvas and the ordinate of the first text
	private final float TEXT2_HEIGHT_RATIO = 1 / 2.0F; //The ratio between the height of the canvas and the ordinate of the second text
	private final float TEXT3_HEIGHT_RATIO = 5 / 6.0F; //The ratio between the height of the canvas and the ordinate of the third text
	
	private Paint paint; //The paint which is used to draw the view
	
	private RectF ovalBoundaries; //The rectangle in which the oval is inscribed
	
	private final int STROKE_WIDTH = 5; //The width of the lines
	
	private final float OVAL_MIN_RADIUS_RATIO = 1 / 7.0F; //The width of the minimal radius
	private final int INITIAL_DEGREE = 90; //The starting point on which the arc has to be drawn
	private final int DEGREES_NUMBER = 180; //What part of the oval, in terms of degrees, has to be drawn
	
	/**
	 * @author Andreas Scalas
	 * 
	 * The simplest constructor, based only on the context.
	 * @param context the context.
	 */
	public CompositeStats(Context context) {
		
		this(context, null);
		
	}

	/**
	 * @author Andreas Scalas
	 * 
	 * A constructor based on the context and on a set of attributes.
	 * @param context the context.
	 * @param attrs the set of attributes.
	 */
	public CompositeStats(Context context, AttributeSet attrs) {

		this(context, attrs, 0);
		
	}

	/**
	 * @author Andreas Scalas
	 * 
	 * A constructor based on the context, a set of attributes and a defined style.
	 * @param context the context.
	 * @param attrs the set of attributes.
	 * @param defStyleAttr the style.
	 */
	public CompositeStats(Context context, AttributeSet attrs, int defStyleAttr) {

		super(context, attrs, defStyleAttr); 
		
		this.text1 = this.text2 = this.text3 = "";
		
		paint = new Paint();
        
        ovalBoundaries = new RectF();
        
	}
	
	/**
	 * @author Andreas Scalas
	 * 
	 * Method that draw the canvas with the defined properties.
     * @param canvas the canvas on which draw object's appearance.
	 */
	@Override
	protected void onDraw(Canvas canvas){
				
		int height, width; //Dimensions of the canvas
		int textSize; 
		int textMinAxisPos, text1OrdinatePos, text2OrdinatePos, text3OrdinatePos, shift; //Spatial positions of the texts
		int firstRawOdinatePos, secondRawOrdinatePos; //Spatial positions of the lines
		int minRadius; //The minimal radius of the oval
		
		//Obtains the dimensions of the canvas.
		height = canvas.getHeight();
		width = canvas.getWidth();
        
		textSize = (int) (width * TEXT_SIZE_RATIO); //Defines the text size
		paint.setTextSize(textSize);
        paint.setAntiAlias(true);

		shift = (int) (textSize * TEXT_SHIFT_RATIO); //Defines how much the text has to be shifted in order to center it
		textMinAxisPos = (int) (width * MIN_WIDTH_RATIO); //Defines the minimal axis in which the text is written
		text1OrdinatePos = (int) (height * TEXT1_HEIGHT_RATIO + shift); //Defines the vertical position of text1
		text2OrdinatePos = (int) (height * TEXT2_HEIGHT_RATIO + shift); //Defines the vertical position of text2
		text3OrdinatePos = (int) (height * TEXT3_HEIGHT_RATIO + shift); //Defines the vertical position of text3
		
		firstRawOdinatePos = height / 3; //Defines the vertical position of the first raw
		secondRawOrdinatePos = 2 * height / 3; //Defines the vertical position of the second raw
		
		//Defines the rectangle in which the oval is contained
		minRadius = (int) (width * OVAL_MIN_RADIUS_RATIO);
		ovalBoundaries.set(width - minRadius, 0, width + minRadius, height);
		
		//Draws the texts
    	canvas.drawText(getText1(), textMinAxisPos, text1OrdinatePos, paint);
    	canvas.drawText(getText2(), textMinAxisPos, text2OrdinatePos, paint);
    	canvas.drawText(getText3(), textMinAxisPos, text3OrdinatePos, paint);
    	
    	/*Draws external straight lines of the "grid". Since an half of the width of the external lines is lost, 
    	it sets the width as 2 * wanted width. Watch attached documentation in order to understand the shape of the "grid"*/
		paint.setStrokeWidth(STROKE_WIDTH * 2); 
    	canvas.drawLine(0, 0, width - 1, 0, paint);
    	canvas.drawLine(width - 1, height, 0, height, paint);
    	canvas.drawLine(0, height, 0, 0, paint);
    	
    	//Draws two straight lines that split up the grid in three parts
    	paint.setStrokeWidth(STROKE_WIDTH);
    	canvas.drawLine(0, firstRawOdinatePos, width - 1,  firstRawOdinatePos, paint);
    	canvas.drawLine(0, secondRawOrdinatePos, width - 1,  secondRawOrdinatePos, paint);
    	
    	//Draws a white oval in order to delete the parts of the previous two lines that are outside of the "grid" 
    	paint.setColor(getResources().getColor(R.color.foreground_color));
    	paint.setStyle(Style.FILL_AND_STROKE);
    	canvas.drawArc(ovalBoundaries, INITIAL_DEGREE, DEGREES_NUMBER, false, paint);
    	
    	//Draws the boundaries of the left half of an oval that represent the boundaries of the right side of the "grid"
    	paint.setColor(Color.BLACK);
    	paint.setStyle(Style.STROKE);
    	canvas.drawArc(ovalBoundaries, INITIAL_DEGREE, DEGREES_NUMBER, false, paint);	

		paint.reset(); //Since the Paint is reused, it has to be reset 
		
	}

	/**
	 * @author Andreas Scalas
	 * @return
	 */
	public String getText1() {
		return text1;
	}

	/**
	 * @author Andreas Scalas
	 * @param text1
	 */
	public void setText1(String text1) {
		this.text1 = text1;
	}

	/**
	 * @author Andreas Scalas
	 * @return
	 */
	public String getText2() {
		return text2;
	}

	/**
	 * @author Andreas Scalas
	 * @param text2
	 * @return
	 */
	public String setText2(String text2) {
		this.text2 = text2;
		return text2;
	}

	/**
	 * @author Andreas Scalas
	 * @return
	 */
	public String getText3() {
		return text3;
	}

	/**
	 * 
	 * @param text3
	 * @return
	 */
	public String setText3(String text3) {
		this.text3 = text3;
		return text3;
	}
	
}
